/**
 * AbstractGenerator.java
 * 2012-3-3 上午12:49:06
 */
package xgenerator.generators;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;

import xgenerator.model.ModelMetadata;

import freemarker.template.Configuration;
import freemarker.template.Template;

/**
 * <p>
 * Title:类的中文名
 * </p>
 * <p>
 * Description:具体功能见各方法描述
 * </p>
 * <p>
 * Copyright:Copyright (c) 2012
 * </p>
 * 
 * @author <a href="mailto:lishushan@gmail.com">liss</a>
 * @version 1.0
 */
public abstract class AbstractGenerator implements Generator {

	/**
	 * 默认模板文件目录
	 */
	public static final String DEFAULT_TEMPLATES_DIR = System.getProperty("user.dir") + File.separator + "templates";
	
	/**
	 * freemarker template Configuration;
	 */
	public static final Configuration CONFIG = new Configuration();
	
	/**
	 * static init
	 */
	static {
		try {
			CONFIG.setDirectoryForTemplateLoading(new File(DEFAULT_TEMPLATES_DIR));
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * <p>
	 * Title：生成代码文件，提供给子类用来生成代码文件
	 * </p>
	 * @param modelMetadata
	 * @param templateFile
	 * @param codeFilePath
	 * @param codeFileName
	 */
	protected String generateCode(ModelMetadata modelMetadata, String templateFile, String codeFilePath, String codeFileName) {
		try {
			/*
			 * 创建数据模型
			 */
			Map root = new HashMap();
			root.put("modelMetadata", modelMetadata);
			
			/*
			 *  使用Configuration实例来加载指定模板
			 */
			Template template = CONFIG.getTemplate(templateFile);
			template.setEncoding(modelMetadata.getEncoding());
			
			/*
			 * 代码目录与文件
			 */
			File fileDir = new File(codeFilePath);
			if(!fileDir.exists()) {
				fileDir.mkdirs();
			}
			File codeFile = new File(codeFilePath + File.separator + codeFileName);
			System.out.println("generate file " + codeFile);
			FileOutputStream fos = new FileOutputStream(codeFile);
			OutputStreamWriter out = new OutputStreamWriter(fos, modelMetadata.getEncoding());
			BufferedWriter bw = new BufferedWriter(out);
			
			/*
			 * 合并处理数据与模型
			 */
			template.process(root, bw);
			bw.flush();
			bw.close();
			
			return codeFile.getAbsolutePath();
		} catch (Exception e) {
			//throw new RuntimeException("generate " + codeFileName + " failure！", e);
			throw new RuntimeException(e.getMessage(), e);
		}
	}
}
